<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>14_key</title>
</head>
<body>

<div id="demo">
  <div>
    <button @click="add">add first</button>
    &nbsp;
    <button @click="remove">remove first</button>
    &nbsp;
    <button @click="sort">sort</button>
  </div>

  <h2>使用id作为key</h2>
  <ul>
    <li v-for="p in persons" :key="p.id">
      {{p.id}}--{{p.name}}--{{p.age}}--<input/>
    </li>
  </ul>

  <h2>使用index作为key</h2>
  <ul>
    <li v-for="(p, index) in persons" :key="index">
      {{p.id}}--{{p.name}}--{{p.age}}--<input/>
    </li>
  </ul>
</div>

<script type="text/javascript" src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.9/vue.js"></script>
<script type="text/javascript">
  new Vue({
    el: '#demo',
    data: {
      persons: [
        {id: 1, name: 'Tom', age: 13},
        {id: 2, name: 'Jack', age: 12}
      ]
    },

    methods: {
      add() {
        this.persons.unshift({id: this.persons.length + 1, name: 'Bob', age: 14})
      },

      remove() {
        this.persons.shift()
      },

      sort() {
        this.persons.sort((p1, p2) => p1.age - p2.age)
      }
    }
  })

  /*
   面试题:
      1). react/vue中的key的作用/内部原理
      2). 为什么列表的key尽量不要用index
   1. 虚拟DOM的key的作用?
      1). 简单的说: key是虚拟DOM对象的标识, 在更新显示时key起着极其重要的作用
      2). 详细的说: 当列表数组中的数据发生变化生成新的虚拟DOM后, React进行新旧虚拟DOM的diff比较
          a. key没有变(有一个对应的)
              item数据没变, 直接使用原来的真实DOM
              item数据变了, 对原来的真实DOM进行数据更新
          b. key变了(没有一个对应)
              销毁原来的真实DOM, 根据item数据创建新的真实DOM显示(即使item数据没有变)
   2. key为index的问题
      1). 添加/删除/排序 => 产生没有必要的真实DOM更新 ==> 界面效果没问题, 但效率低
      2). 如果item界面还有输入框 => 产生错误的真实DOM更新 ==> 界面有问题
      注意: 如果不存在添加/删除/排序操作, 用index没有问题
   3. 解决:
      使用item数据的标识数据作为key, 比如id属性值

      [
        {id: 1, name: 'Tom', age: 13},
        {id: 2, name: 'Jack', age: 12}
      ]
    index作为key
      vLi0      tom       ==> li(tom)
      vLi1      jack      ==> li(jack)

      [
        {id: 3, name: 'bob', age: 15}
        {id: 1, name: 'Tom', age: 13},
        {id: 2, name: 'Jack', age: 12}
      ]
      vLi0    bob    ==> 复用 li(tom) ==> 更新dom的数据    ===> 应该要新创建的, 但复用一个错误的真实DOM
      vLi1    tom    ==> 复用 li(jack) ==> 更新dom的数据   ==> 应该要复用原本的, 但复用一个错误的真实DOM
      vLi2    jack   ==> 新建 li(jack)                    ==> 应该要复用原本的
    id作为key
      vLi1      tom       ==> li(tom)
      vLi2      jack      ==> li(jack)

      vLi3    bob    ==> 新建 li(bob) ==> 新创建一个li显示
      vLi1    tom    ==> 复用 li(tom) ==> 直接复用li
      vLi2    jack   ==> 复用 li(jack)  ==> 直接复用li

      下标作为key的问题?
          至少效率的问题?  复用了其它数据对应的真实DOM(key变化了)
          可能会有效果的问题?  如果每行都一个输入框且输入的数据(key变化了, 复用了错误的真实DOM)
      好的处理: 要保证数据key的稳定性 ==> 同一个数据的key后面不要再发生变化, 即使内部数据发生了变化
          下标是不稳定的, 而id比较稳定
   */

</script>

<script>
  function sort(arr) {
    
  }

  const arr = ['# a', '## b', '## c', '### d', '### e', '# f']
  
</script>
</body>
</html>